package com.zjsru.plan2024.oneday;

/**
 * 获取提示
 * 299. 猜数字游戏
 *
 * @Author: cookLee
 * @Date: 2024-03-10
 * @date 2024/03/10
 */
public class GetHint {

    /**
     * 主
     * \
     * 猜测数字中有多少位属于数字和确切位置都猜对了（称为 "Bulls"，公牛），
     * 有多少位属于数字猜对了但是位置不对（称为 "Cows"，奶牛）。也就是说，这次猜测中有多少位非公牛数字可以通过重新排列转换成公牛数字。
     * 提示的格式为 "xAyB" ，x 是公牛个数， y 是奶牛个数，A 表示公牛，B 表示奶牛。
     * \
     * 输入：secret = "1807", guess = "7810"
     * 输出："1A3B"
     * "1807"
     *   |
     * "7810"
     * \
     * 输入：secret = "1123", guess = "0111"
     * 输出："1A1B"
     * 解释：
     * "1123"        "1123"
     *   |      or     |
     * "0111"        "0111"
     * 注意，两个不匹配的 1 中，只有一个会算作奶牛（数字猜对位置不对）。通过重新排列非公牛数字，其中仅有一个 1 可以成为公牛数字。
     * \
     * @param args args
     */
    public static void main(String[] args) {
        GetHint getHint = new GetHint();
        String secret = "1807";
        String guess = "7810";
        System.out.println(getHint.getHint2(secret, guess));
    }

    /**
     * 获取提示:模拟
     *
     * @param secret 秘密
     * @param guess  猜猜
     * @return {@link String}
     */
    public String getHint(String secret, String guess) {
        //定义要求的公牛数字
        int bull = 0;
        //定义要求的奶牛数字
        int cow = 0;
        //定义两个数组存储两个字符串各个位置数的值，限定位数10即可 0-9 10位数字
        int[] secrets = new int[10];
        int[] guesses = new int[10];

        for (int i = 0; i < secret.length(); i++) {
            if ((secret.charAt(i) - '0') == (guess.charAt(i) - '0')) {
                bull++;
            } else {
                //记录同一位上存在值的个数
                secrets[secret.charAt(i) - '0']++;
                guesses[guess.charAt(i) - '0']++;
            }
        }
        //获取奶牛数（位置不同，数字得存在） 所以用min方法获取两个数组共同存在得值的最小值。举例：如果一方存在则返回0
        for (int i = 0; i < 10; i++) {
            cow += Math.min(secrets[i], guesses[i]);
        }
        return bull + "A" + cow + "B";
    }

    /**
     * 一次遍历
     *
     * @param secret 秘密
     * @param guess  猜猜
     * @return {@link String}
     */
    public String getHint2(String secret, String guess) {
        //定义要求的公牛数字
        int bull = 0;
        //定义要求的奶牛数字
        int cow = 0;
        //定义两个数组存储两个字符串各个位置数的值，限定位数10即可 0-9 10位数字
        int[] total = new int[10];

        for (int i = 0; i < secret.length(); i++) {
            if ((secret.charAt(i) - '0') == (guess.charAt(i) - '0')) {
                bull++;
            } else {
                if (total[secret.charAt(i) - '0']++ < 0) {
                    cow++;
                }
                if (total[guess.charAt(i) - '0']-- > 0) {
                    cow++;
                }
            }
        }
        return bull + "A" + cow + "B";
    }

}
